import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';

import cn from 'classnames';
import { gql, useMutation, useQuery } from '@apollo/client';

import { withRouter } from 'react-router';
import { Link } from 'react-router-dom';
import fetch from 'API/fetch';

import {
	Search24 as SearchIcon,
	DotMark16 as DotMarkIcon,
} from '@carbon/icons-react';

import Select, { Option } from '@kuiper-components/select';
import Button from '@kuiper-components/button';
import Input from '@kuiper-components/input';
import Table, {
	searchStringBuilder as tableSearchStringBuilder,
} from '@kuiper-components/page-table';

import MessageNav from '../MessageNav';
import { datetime } from '../../../../common/formatter';

import confirm from '../../../components/confirm';
import CheckboxGroup from '../../../components/CheckboxGroup';
import notification from '@kuiper-components/notification';

import Breadcrumb, { Item } from '../../../components/Breadcrumb';
import s from './NotificationCentre.module.css';

const routePrefix = '/message/notification-centre';

const CATEGORY_OPTIONS = [
	{label: 'Web漏洞', value: 'vul'},
	{label: 'SSL安全', value: 'ssl'},
	{label: '安全事件', value: 'securityEvent'},
  {label: '篡改', value: 'changeCheck'},
	{label: '内容违规', value: 'content'},
	{label: '资产变动', value: 'asset'},
	{label: '可用性', value: 'aviliable'},
	{label: '主机安全', value: 'hostVul'}
]
const CHECK_BOX_OPTIONS = [{ label: '只看未读', value: 'unread' }];

const REMOVE_NOTIFICATION_MANY = gql`
	mutation($ids: [MongoID]) {
		NotificationRemoveMany(filter: { _ids: $ids }) {
			numAffected
		}
	}
`;

export const fieldsFragment = gql`
	fragment NotificationFields on Notification {
		_id
		title
		category
		message
		from
		level
		data
		datetime
		isMarkedMap
		choosedActionMap
		action
	}
`;

function NotificationCentre({ className, history, location: { search } }) {
	const [userInfo, setUserInfo] = useState({
		identified: true,
		uid: ""
	})

	let refetch = () => {};
	const searchStringBuilder = tableSearchStringBuilder.bind(null, search);
	const columnsBuilder = () => [
		{
			title: '',
			dataIndex: 'mark',
			key: 'mark',
			width: 25,
			// eslint-disable-next-line react/display-name
			render: (x, record) => (
				<span>
					{!record?.isMarkedMap[userInfo?.uid] && <DotMarkIcon className={s.markIcon} />}
				</span>
			),
		},
		{
			title: '标题',
			dataIndex: 'title',
			key: 'title',
			width: 480,
			// eslint-disable-next-line react/display-name
			render: (data, record) => {
				return (
					<Link
						className={cn(s.link, {
							[s.highLight]: !record?.isMarkedMap[userInfo?.uid],
						})}
						to={`/message/notification-centre/${record._id}`}
					>
						<div className={s.text} title={data}>
							{data}
						</div>
					</Link>
				);
			},
		},
		{
			title: '消息类型',
			dataIndex: 'data',
			key: 'tasktype',
			render: data => CATEGORY_OPTIONS.reduce((t, i) => {
				t[i.value] = i.label
				return t
			}, {})[data?.taskCategory],
		},
		{
			title: '通知时间',
			dataIndex: 'datetime',
			key: 'datetime',
			render: datetime,
		},
		{
			title: '操作',
			dataIndex: 'action',
			key: 'action',
			width: 64,
			// eslint-disable-next-line react/display-name
			render: (_action, record) => {
				return (
					<Button primary link onClick={() => handleDeleteOne(record._id)}>
						删除
					</Button>
				);
			},
		},
	];
	const urlFilterVal = JSON.parse(
		new URLSearchParams(search).get('filter') || '{}'
	);
	const [selectedRows, handleRowSelect] = React.useState({});
	const [disabledCla, setDisabledCla] = React.useState('disabled');
	const [readStatus, setReadStatus] = React.useState({});
	const [filter, setFilter] = React.useState(urlFilterVal.titleSearch);
	const [removeMany] = useMutation(REMOVE_NOTIFICATION_MANY);

	const handleDeleteOne = id => {
		confirm.warning({
			message: '您确定要删除该条告警信息？',
			okText: '删除',
			cancelText: '取消',
			onOk: () =>
				removeMany({ variables: { ids: [id] } }).then(() => {
					notification.success({
						message: `删除成功`,
						placement: 'top',
					});
					refetch();
				}),
		});
	};
	const handleReplyAll = async () => {
		const params = Object.entries(selectedRows).map(([type]) => {
			return type;
		});
		const res = await fetch('/api/v2/mail/mark', {
			method: 'POST',
			body: JSON.stringify({ mail_ids: params }),
		});
		if (res.code === 200) {
			handleRowSelect({});
			refetch();
		}
	};
	const handleRemoveAll = () => {
		const ids = Object.entries(selectedRows).reduce((arr, [id, val]) => {
			if (val) arr.push(id);
			return arr;
		}, []);
		if (ids.length === 0) return;
		confirm.warning({
			message: '您确定要批量删除多条告警信息？该操作不可逆',
			okText: '删除',
			cancelText: '取消',
			onOk: () =>
				removeMany({
					variables: {
						ids,
					},
				}).then(() => refetch()),
		});
	};
	const handleFilterChange = filter => {
		const search = searchStringBuilder({
			filter: JSON.stringify(filter),
			page: 1,
			sort: '_ID_DESC',
		});
		history.replace(`${routePrefix}?${search}`);
	};

	const handleCategoryChange = value => {
		if (!value) {
			handleFilterChange({ ...urlFilterVal, data: undefined });
			return;
		}
		handleFilterChange({ ...urlFilterVal, data: { taskCategory: value } });
	};

	const handleConfirm = () =>
		handleFilterChange({ titleSearch: filter.trim() });

	const handleChange = value => {
		if (!value) handleFilterChange({ titleSearch: undefined });
		setFilter(value);
	};

	const handleCheckChange = value => {
		const status = { ...readStatus, ...value };
		setReadStatus(status);
		const filterParams = { titleSearch: filter };
		if (!!status.read && !status.unread) {
			filterParams.markStatus = { [userInfo?.uid]: true };
		} else if (!status.read && !!status.unread) {
			filterParams.markStatus = { [userInfo?.uid]: false };
		}
		handleFilterChange(filterParams);
	};
	async function getIdentified() {
		const res = await fetch(`/api/v2/users/user_info`, {
			method: 'GET',
		}).catch(e => {
			return {};
		});
		if (res.code === 200) {
			setUserInfo(res.results);
		}
	}
	useEffect(() => {
		getIdentified()
	},[])
	return (
		<div
			className={cn(className, s.notificationContainer)}
			style={!userInfo?.identified ? { top: '5.25rem' } : {}}
		>
			<MessageNav />
			<div className={s.notificationCentre}>
				<Breadcrumb className={s.breadcrumb}>
					<Item disabled={true}>消息中心</Item>
					<Item>告警通知</Item>
				</Breadcrumb>
				<div className={s.content}>
					<div className={s.toolbox}>
						<Input
							type="search"
							placeholder="搜索标题内容"
							className={cn(className, s.hostFilterInput)}
							after={
								<SearchIcon className={s.searchIcon} onClick={handleConfirm} />
							}
							value={filter}
							onChange={handleChange}
							onPressEnter={handleConfirm}
						/>
						<div className={s.selectContainer}>
							<Select
								className={s.select}
								allowClear
								placeholder="消息类型"
								onChange={handleCategoryChange}
							>
								{CATEGORY_OPTIONS.map(({ label, value }) => (
									<Option key={value} value={value}>
										{label}
									</Option>
								))}
							</Select>
							<CheckboxGroup
								className={s.checkBox}
								checked={readStatus}
								options={CHECK_BOX_OPTIONS}
								onChange={handleCheckChange}
							/>
						</div>
					</div>
					<div className={s.tableWrapper}>
						<Table
							className={s.table}
							routePrefix={routePrefix}
							columns={columnsBuilder()}
							fieldName="Notification"
							fieldsFragment={fieldsFragment}
							defaultFilter={{ category: '告警通知' }}
							fieldsFragmentName="NotificationFields"
							rowSelected={selectedRows}
							onRowSelectionChange={selectedRows => {
								handleRowSelect(selectedRows);
								JSON.stringify(selectedRows) === '{}'
									? setDisabledCla('disabled')
									: setDisabledCla('btn');
							}}
							getRefetch={x => {
								refetch = x;
							}}
							rightBottomContent={
								<div className={s.actions}>
									<Button className={s[disabledCla]} onClick={handleRemoveAll}>
										删除
									</Button>
									<Button className={s[disabledCla]} onClick={handleReplyAll}>
										标记已读
									</Button>
								</div>
							}
						/>
					</div>
				</div>
			</div>
		</div>
	);
}

NotificationCentre.propTypes = {
	className: PropTypes.string,
	history: PropTypes.shape({
		push: PropTypes.func.isRequired,
		replace: PropTypes.func.isRequired,
	}).isRequired,
	location: PropTypes.shape({
		search: PropTypes.string.isRequired,
	}).isRequired,
	match: PropTypes.shape({
		params: PropTypes.shape({
			taskType: PropTypes.string,
		}).isRequired,
	}).isRequired,
};

NotificationCentre.defaultProps = {
	className: '',
};

export default withRouter(NotificationCentre);
